package org.jeecg.modules.demo.roomapartdistribute.controller;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.applyapartemployee.entity.ZnzfApplyApartEmployee;
import org.jeecg.modules.demo.applyapartemployee.service.IZnzfApplyApartEmployeeService;
import org.jeecg.modules.demo.applyinfo.entity.ZnzfApply;
import org.jeecg.modules.demo.applyinfo.entity.ZnzfDetermineApart;
import org.jeecg.modules.demo.applyinfo.service.IZnzfApplyService;
import org.jeecg.modules.demo.applyinfo.service.IZnzfDetermineApartService;
import org.jeecg.modules.demo.base.entity.ZnzfEmployee;
import org.jeecg.modules.demo.base.service.IZnzfEmployeeService;
import org.jeecg.modules.demo.checkemployee.entity.ZnzfCheckEmployee;
import org.jeecg.modules.demo.checkemployee.service.IZnzfCheckEmployeeService;
import org.jeecg.modules.demo.projectroom.entity.ZnzfProject;
import org.jeecg.modules.demo.projectroom.entity.ZnzfRoom;
import org.jeecg.modules.demo.projectroom.service.IZnzfProjectService;
import org.jeecg.modules.demo.projectroom.service.IZnzfRoomService;
import org.jeecg.modules.demo.roomapartdistribute.entity.ZnzfCheckApart;
import org.jeecg.modules.demo.roomapartdistribute.entity.ZnzfCheckApartRoomList;
import org.jeecg.modules.demo.roomapartdistribute.entity.ZnzfRoomApartDistribute;
import org.jeecg.modules.demo.roomapartdistribute.service.IZnzfCheckApartRoomListService;
import org.jeecg.modules.demo.roomapartdistribute.service.IZnzfCheckApartService;
import org.jeecg.modules.demo.roomapartdistribute.service.IZnzfRoomApartDistributeService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.system.entity.SysAnnouncement;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysAnnouncementService;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

 /**
 * @Description: 房源单位分配
 * @Author: jeecg-boot
 * @Date:   2022-03-18
 * @Version: V1.0
 */
@Api(tags="房源单位分配")
@RestController
@RequestMapping("/roomapartdistribute/znzfRoomApartDistribute")
@Slf4j
public class ZnzfRoomApartDistributeController extends JeecgController<ZnzfRoomApartDistribute, IZnzfRoomApartDistributeService> {
	@Autowired
	private IZnzfRoomApartDistributeService znzfRoomApartDistributeService;

	 @Autowired
	 private ISysUserService sysUserService;

	 @Autowired
	 private IZnzfApplyService znzfApplyService;

	 @Autowired
	 private IZnzfDetermineApartService znzfDetermineApartService;

	 @Autowired
	 private IZnzfApplyApartEmployeeService znzfApplyApartEmployeeService;

	 @Autowired
	 private IZnzfCheckApartService znzfCheckApartService;

	 @Autowired
	 private IZnzfCheckEmployeeService znzfCheckEmployeeService;

	 @Autowired
	 private IZnzfCheckApartRoomListService znzfCheckApartRoomListService;

	 @Autowired
	 private ISysDepartService sysDepartService;

	 @Autowired
	 private ISysAnnouncementService sysAnnouncementService;

	 @Autowired
	 private IZnzfProjectService znzfProjectService;

	 @Autowired
	 private IZnzfEmployeeService znzfEmployeeService;

	 @Autowired
	 private IZnzfRoomService znzfRoomService;

	/**
	 * 分页列表查询
	 *
	 * @param znzfRoomApartDistribute
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	//@AutoLog(value = "房源单位分配-分页列表查询")
	@ApiOperation(value="房源单位分配-分页列表查询", notes="房源单位分配-分页列表查询")
	@GetMapping(value = "/list")
	public Result<IPage<ZnzfRoomApartDistribute>> queryPageList(ZnzfRoomApartDistribute znzfRoomApartDistribute,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<ZnzfRoomApartDistribute> queryWrapper = QueryGenerator.initQueryWrapper(znzfRoomApartDistribute, req.getParameterMap());
		Page<ZnzfRoomApartDistribute> page = new Page<ZnzfRoomApartDistribute>(pageNo, pageSize);
		IPage<ZnzfRoomApartDistribute> pageList = znzfRoomApartDistributeService.page(page, queryWrapper);
		List<ZnzfRoomApartDistribute> znzfRoomApartDistributeList = pageList.getRecords();
		for(ZnzfRoomApartDistribute distribute : znzfRoomApartDistributeList){
			ZnzfApply znzfApply = znzfApplyService.getById(distribute.getApplyInfo());
			ZnzfProject znzfProject = znzfProjectService.getById(znzfApply.getProject());
			if (znzfProject != null)
				distribute.setProjectName(znzfProject.getName());
		}
		pageList.setRecords(znzfRoomApartDistributeList);
		return Result.OK(pageList);
	}
	
	/**
	 *   添加
	 *
	 * @param znzfRoomApartDistribute
	 * @return
	 */
	@AutoLog(value = "房源单位分配-添加")
	@ApiOperation(value="房源单位分配-添加", notes="房源单位分配-添加")
	@PostMapping(value = "/add")
	public Result<String> add(@RequestBody ZnzfRoomApartDistribute znzfRoomApartDistribute) {
		znzfRoomApartDistributeService.save(znzfRoomApartDistribute);
		return Result.OK("添加成功！");
	}
	
	/**
	 *  编辑
	 *
	 * @param znzfRoomApartDistribute
	 * @return
	 */
	@AutoLog(value = "房源单位分配-编辑")
	@ApiOperation(value="房源单位分配-编辑", notes="房源单位分配-编辑")
	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	public Result<String> edit(@RequestBody ZnzfRoomApartDistribute znzfRoomApartDistribute) {
		znzfRoomApartDistributeService.updateById(znzfRoomApartDistribute);
		List<ZnzfCheckApart> znzfCheckApartList = znzfCheckApartService.searchsByZnzfRoomApartDistributeId(znzfRoomApartDistribute.getId());
		for(ZnzfCheckApart znzfCheckApart : znzfCheckApartList){
			double tmp = znzfCheckApart.getApartPeopleApplyRatio() * znzfRoomApartDistribute.getRoomNum();
			znzfCheckApart.setCheckedRoomNum((int)(tmp + 0.5));
			znzfCheckApart.setRoomRatio(tmp);
			znzfCheckApartService.updateById(znzfCheckApart);
		}
		return Result.OK("编辑成功!");
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "房源单位分配-通过id删除")
	@ApiOperation(value="房源单位分配-通过id删除", notes="房源单位分配-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		znzfRoomApartDistributeService.removeById(id);
		return Result.OK("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "房源单位分配-批量删除")
	@ApiOperation(value="房源单位分配-批量删除", notes="房源单位分配-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.znzfRoomApartDistributeService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	//@AutoLog(value = "房源单位分配-通过id查询")
	@ApiOperation(value="房源单位分配-通过id查询", notes="房源单位分配-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<ZnzfRoomApartDistribute> queryById(@RequestParam(name="id",required=true) String id) {
		ZnzfRoomApartDistribute znzfRoomApartDistribute = znzfRoomApartDistributeService.getById(id);
		if(znzfRoomApartDistribute==null) {
			return Result.error("未找到对应数据",null);
		}
		return Result.OK(znzfRoomApartDistribute);
	}

	/**
	 * 通过radId查询所有房源信息
	 *
	 * @param radId
	 * @return
	 */
	@ApiOperation(value="房源单位分配-通过radId查询所有房源信息", notes="房源单位分配-通过radId查询所有房源信息")
	@GetMapping(value = "/queryRoomListByRadId")
	public Result<List<ZnzfRoom>> queryRoomListByRadId(@RequestParam(name="radId",required=true) String radId) {
		List<ZnzfRoom> znzfRoomList = znzfRoomApartDistributeService.searchRoomListByRadId(radId);
		if(znzfRoomList==null) {
			return Result.error("未找到对应数据",null);
		}
		return Result.OK(znzfRoomList);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param znzfRoomApartDistribute
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, ZnzfRoomApartDistribute znzfRoomApartDistribute) {
        return super.exportXls(request, znzfRoomApartDistribute, ZnzfRoomApartDistribute.class, "房源单位分配");
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, ZnzfRoomApartDistribute.class);
    }

	 /**
	  * 停止报名后将报名信息转换为房源单位分配信息
	  * @param object
	  * @param request
	  * @return
	  */
	 @AutoLog(value = "房源单位分配-点击结束按钮,报名信息转换为房源单位分配信息")
	 @ApiOperation(value="房源单位分配-点击结束按钮报名信息转换为房源单位分配信息", notes="房源单位分配-点击结束按钮报名信息转换为房源单位分配信息")
	 @PostMapping(value = "/znzfApplyToZnzfRoomApartDistribute")
	 public Result<String> znzfApplyToZnzfRoomApartDistribute(@RequestBody JSONObject object, HttpServletRequest request) {
		 String applyId = (String) object.get("applyId");
		 String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
		 String name = JwtUtil.getUsername(token);
		 SysUser sysUser = sysUserService.getUserByName(name);
		 if(name == null || sysUser == null)
		 	return Result.error("账号异常");
		 ZnzfApply znzfApply = znzfApplyService.getById(applyId);
		 if(znzfApply == null)
			 return Result.error("报名信息异常");
		 znzfApply.setIsStopApply(1);
		 znzfApply.setCurrentStatus(1 + "");
		 znzfApplyService.updateById(znzfApply);
		 ZnzfRoomApartDistribute znzfRoomApartDistribute = new ZnzfRoomApartDistribute();
		 znzfRoomApartDistribute.setApplyInfo(znzfApply.getId());
		 znzfRoomApartDistribute.setRoomNum(0);
		 znzfRoomApartDistribute.setTitle(znzfApply.getTitle());
		 List<ZnzfDetermineApart> znzfDetermineApartList = znzfDetermineApartService.searchsByApplyListId(applyId);
		 int cnt = 0;
		 for(ZnzfDetermineApart znzfDetermineApart : znzfDetermineApartList){
		 	List<ZnzfApplyApartEmployee> znzfApplyApartEmployeeList = znzfApplyApartEmployeeService.searchsByCheckDetermineApartId(znzfDetermineApart.getId());
		 	cnt = cnt + znzfApplyApartEmployeeList.size();
		 }
		 znzfRoomApartDistribute.setApplyNumSum(cnt + "");
		 znzfRoomApartDistribute.setIsLock(0);
		 znzfRoomApartDistribute.setStatus(0);
		 znzfRoomApartDistribute.setIsEnd(0);
		 znzfRoomApartDistributeService.save(znzfRoomApartDistribute);
		 for(ZnzfDetermineApart znzfDetermineApart : znzfDetermineApartList){
			 List<ZnzfApplyApartEmployee> znzfApplyApartEmployeeList = znzfApplyApartEmployeeService.searchsByCheckDetermineApartId(znzfDetermineApart.getId());
			 ZnzfCheckApart znzfCheckApart = new ZnzfCheckApart();
			 znzfCheckApart.setApartId(znzfDetermineApart.getApartId());
			 znzfCheckApart.setApartCheckPeopleNum(znzfApplyApartEmployeeList.size());
			 znzfCheckApart.setApplyNumSum(cnt);
			 double apartCheckPeopleNum = znzfApplyApartEmployeeList.size() * 1.0;
			 znzfCheckApart.setApartPeopleApplyRatio(apartCheckPeopleNum/cnt);
			 znzfCheckApart.setRoomApartDistributeId(znzfRoomApartDistribute.getId());
			 znzfCheckApart.setCheckedRoomNum(0);
			 znzfCheckApart.setRoomRatio(0.0);
			 znzfCheckApart.setState("-1");
			 znzfCheckApartService.save(znzfCheckApart);
			 if(znzfApplyApartEmployeeList.isEmpty())
				 continue;
			 for(ZnzfApplyApartEmployee znzfApplyApartEmployee : znzfApplyApartEmployeeList){
				 ZnzfCheckEmployee znzfCheckEmployee = new ZnzfCheckEmployee();
				 znzfCheckEmployee.setEmployeeId(znzfApplyApartEmployee.getEmployeeId());
				 znzfCheckEmployee.setUserId(znzfApplyApartEmployee.getUserId());
				 znzfCheckEmployee.setApartId(znzfApplyApartEmployee.getApartId());
				 znzfCheckEmployee.setCheckApartId(znzfCheckApart.getId());
				 znzfCheckEmployee.setRank(znzfApplyApartEmployee.getRank());
				 znzfCheckEmployee.setScore(znzfApplyApartEmployee.getScore());
				 znzfCheckEmployee.setApplyTime(znzfApplyApartEmployee.getApplyTime());
				 znzfCheckEmployee.setIsShortlisted(znzfApplyApartEmployee.getIsShortlisted());
				 znzfCheckEmployeeService.save(znzfCheckEmployee);

				 //发布通知
				 SysAnnouncement sysAnnouncement = new SysAnnouncement();
				 sysAnnouncement.setTitile("您已入围");
				 sysAnnouncement.setMsgAbstract("报名转分配通知");
				 sysAnnouncement.setMsgContent("<p>您申请的公租房的房源已入围，请耐心等待！<p>");
				 sysAnnouncement.setPriority("M");
				 sysAnnouncement.setMsgCategory("1");
				 sysAnnouncement.setMsgType("USER");
				 sysAnnouncement.setSendStatus("1");
				 sysAnnouncement.setUserIds(znzfApplyApartEmployee.getUserId() + ",");
				 sysAnnouncement.setSender("系统");
				 Date time= new Date();
				 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				 formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
				 String now_time = formatter.format(time);
				 Calendar ca = Calendar.getInstance();//得到一个Calendar的实例
				 ca.setTime(new Date()); //设置时间为当前时间
				 ca.add(Calendar.DATE, 30); //日期+30天
				 Date endTime = ca.getTime(); //结果
				 sysAnnouncement.setDelFlag("0");
				 sysAnnouncement.setSendTime(time);
				 sysAnnouncement.setStartTime(time);
				 sysAnnouncement.setEndTime(endTime);
				 sysAnnouncementService.saveAnnouncement(sysAnnouncement);
			 }
		 }
		 return Result.OK("报名信息转房源单位分配成功");
	 }

	 @AutoLog(value = "房源单位分配-分配房源按钮")
	 @ApiOperation(value="房源单位分配-分配房源按钮", notes="房源单位分配-分配房源按钮")
	 @PostMapping(value = "/DistributeRoom")
	 public Result<String> DistributeRoom(@RequestParam("radId") String radId) {
	 	ZnzfRoomApartDistribute znzfRoomApartDistribute = znzfRoomApartDistributeService.getById(radId);
	 	if(znzfRoomApartDistribute == null){
	 		return Result.error("该房源分配项目不存在");
		}
	 	List<ZnzfCheckApart> znzfCheckApartList = znzfCheckApartService.searchsByZnzfRoomApartDistributeId(radId);
	 	for(ZnzfCheckApart znzfCheckApart : znzfCheckApartList){
	 		List<ZnzfCheckApartRoomList> znzfCheckApartRoomListList = znzfCheckApartRoomListService.searchsByZnzfCheckApartId(znzfCheckApart.getId());
	 		int cnt = znzfCheckApartRoomListList.size();
	 		if(!znzfCheckApart.getCheckedRoomNum().equals(cnt)){
	 			return Result.error("存在单位分配房源错误",znzfCheckApart.getApartId());
			}
		}
	 	znzfRoomApartDistribute.setStatus(1);
	 	znzfRoomApartDistributeService.updateById(znzfRoomApartDistribute);
	 	return Result.OK("房源分配成功！");
	 }


	 @AutoLog(value = "总分配结果审核")
	 @ApiOperation(value = "房源单位分配-对一批单位一对一的房源分配进行审核",notes = "1通过0驳回")
	 @PostMapping(value = "/passOrDenyDeparts")
	 public Result<String> passOrDenyDeparts(@RequestBody JSONObject object){
	 	int ret = object.getIntValue("ret") ;
	 	String note = (String)object.get("note");
		String[] ids = object.getJSONArray("ids").toArray(new String[0]);
	 	if(ret == 0){//驳回
			for(String id : ids){
				String state = znzfCheckApartService.checkState(id);
				if(StringUtils.isNotEmpty(state) && "1".equals(state))
					znzfCheckApartService.passOrDeny(id,note,"2");
				return Result.OK("已驳回");
			}
		}
		else if(ret == 1){
			for(String id : ids){
				String state = znzfCheckApartService.checkState(id);
				if(StringUtils.isNotEmpty(state) && "1".equals(state)){
					znzfCheckApartService.passOrDeny(id,note,"0");
					List<ZnzfCheckApartRoomList> znzfCheckApartRoomListList = znzfCheckApartRoomListService.searchsByZnzfCheckApartId(id);
					for(ZnzfCheckApartRoomList znzfCheckApartRoomList : znzfCheckApartRoomListList){
						ZnzfEmployee znzfEmployee = znzfEmployeeService.searchByUid(znzfCheckApartRoomList.getUid());
						znzfEmployee.setRoomId(znzfCheckApartRoomList.getRoomId());
						znzfEmployeeService.updateById(znzfEmployee);
						ZnzfRoom znzfRoom = znzfRoomService.getById(znzfCheckApartRoomList.getRoomId());
						znzfRoom.setLivedNum(znzfRoom.getLivedNum() + 1);
						znzfRoomService.updateById(znzfRoom);
						//发布通知
						SysAnnouncement sysAnnouncement = new SysAnnouncement();
						sysAnnouncement.setTitile("您的轮候房源已通过");
						sysAnnouncement.setMsgAbstract("房源通知");
						sysAnnouncement.setMsgContent("<p>您申请的公租房的房源已通过，房源为"
								+ znzfRoom.getGroupName() + znzfRoom.getUnit() + znzfRoom.getRoomNo() + "，请于30日内办理入住<p>");
						sysAnnouncement.setPriority("M");
						sysAnnouncement.setMsgCategory("1");
						sysAnnouncement.setMsgType("USER");
						sysAnnouncement.setSendStatus("1");
						sysAnnouncement.setUserIds(znzfCheckApartRoomList.getUid() + ",");
						sysAnnouncement.setSender("系统");
						Date time= new Date();
						SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
						String now_time = formatter.format(time);
						Calendar ca = Calendar.getInstance();//得到一个Calendar的实例
						ca.setTime(new Date()); //设置时间为当前时间
						ca.add(Calendar.DATE, 30); //日期+30天
						Date endTime = ca.getTime(); //结果
						sysAnnouncement.setDelFlag("0");
						sysAnnouncement.setSendTime(time);
						sysAnnouncement.setStartTime(time);
						sysAnnouncement.setEndTime(endTime);
						sysAnnouncementService.saveAnnouncement(sysAnnouncement);
					}
				}
			}
		}
		 return Result.OK("已通过");
	 }

	 @AutoLog(value = "确定为单位分配房源结果")
	 @ApiOperation(value = "房源单位分配-确定房源分配结果",notes = "确定为各单位框房源的结果")
	 @PostMapping("/confirmRoomToDepart")
	 public Result<String> confirmRoomToDepart(@RequestBody JSONObject object){
		String radId = (String) object.get("radId");
		List<ZnzfCheckApart> checkAparts = znzfCheckApartService.searchsByZnzfRoomApartDistributeId(radId);
		for(ZnzfCheckApart checkApart : checkAparts){
			if(!znzfRoomApartDistributeService.roomToDepartEqual(checkApart.getId()))
				return Result.error(
						sysDepartService.getById(checkApart.getApartId()).getDepartName()
								+ "分配房源数量不正确!");
		}
		//更新状态
		 ZnzfRoomApartDistribute table = new ZnzfRoomApartDistribute();
		table.setId(radId);
		table.setStatus(2);//各单位设置中签
		boolean result = znzfRoomApartDistributeService.updateById(table);
	 	if(result)
	 		return Result.OK("分配完成");
	 	return Result.error("更新状态失败!");
	 }
}
